import com.limetalks.data.Stream;
import com.limetalks.data.User;
import com.limetalks.events.LimeEvent;
import com.limetalks.logic.LimeTalks;

import flash.events.MouseEvent;
import flash.events.NetStatusEvent;
import flash.external.ExternalInterface;
import flash.media.Camera;
import flash.media.Microphone;
import flash.net.NetConnection;
import flash.net.NetStream;

import mx.controls.Alert;
import mx.core.Application;
import mx.events.FlexEvent;

private var stream:Stream;
private var mySelf:User;

//network properties
private var connection:NetConnection;
private var inStream:NetStream;
private var outStream:NetStream;

//device properties
private var camera:Camera;
private var microphone:Microphone;
private var red5Url:String = "rtmp://localhost/LimeTalksRed5/";

[Bindable]
public var streamId:int;
//private var inout:String;
private var sessionId:String;

// Assign values to new properties.
private function initVars():void {	
	streamId = Application.application.parameters.streamId;
	sessionId = Application.application.parameters.sid;
}

public function onCreationComplete(event:FlexEvent) : void {

	initVars();
	
	if (ExternalInterface.available) {
		ExternalInterface.addCallback("sendMessage", chatSendMessage);
	}
	
	limeTalks = new LimeTalks();
	limeTalks.addEventListener(LimeEvent.CONNECTION, onConnectionRise);
	limeTalks.addEventListener(LimeEvent.LOGIN, onLogin);
	limeTalks.addEventListener(LimeEvent.LOGIN_ERROR, onLoginError);
	limeTalks.addEventListener(LimeEvent.LOGOUT, onLogout);
	limeTalks.addEventListener(LimeEvent.STREAM_START, onStreamStart);
	limeTalks.addEventListener(LimeEvent.STREAM_STOP, onStreamStop);
	limeTalks.addEventListener(LimeEvent.STREAM_JOIN, onStreamJoin);
	limeTalks.addEventListener(LimeEvent.STREAM_LEAVE, onStreamLeave);
	limeTalks.addEventListener(LimeEvent.STREAM_UPDATE, onStreamUpdate);
	limeTalks.addEventListener(LimeEvent.CHAT_MESSAGE_RECEIVED, onMessageReceive);
	
	limeTalks.connect(streamId,sessionId);
	//log("Connecting to " + limeTalks.connectionUrl + "...");		
}

private function onConnectionRise(event:LimeEvent):void {
	if(event.params.success) {
		log("Connection Success");
		
		if(stream.master.id == mySelf.id) {
			setupOutgoingDevices();
			setupOutgoingStream();		
		} else {
			setupIncominStream();
		}
		
	} else {
		log("Connection Failed: level='" + event.params.level + "' code='" + event.params.code + "' group='" + event.params.group + "'");
	}
}

private function onLogin(event:LimeEvent) : void {
	log("User '" + event.params.user.id + "' login");
	mySelf = event.params.user;
	//limeTalks.startAndJoinStream(streamId);	
}

private function onLoginError(event:LimeEvent) : void {	
	log("Login error");
}

private function onLogout(event:LimeEvent) : void {	
	log("Logout");
}

private function onStreamStart(event:LimeEvent) : void 
{
	log("Stream started: " + event.params.stream.id);
}

private function onStreamStop(event:LimeEvent) : void 
{
	log("Stream stopped: " + event.params.stream.id);
}

private function onStreamJoin(event:LimeEvent) : void 
{
	log("onStreamJoin");
	stream = event.params.stream;
}

private function onStreamLeave(event:LimeEvent) : void 
{
	var user:User = event.params.user;
	var stream:Stream = event.params.stream;	
	if(user.id == stream.master.id){
		log("Master '" + user.name + "'(" + user.id + ") has left the stream '" + stream.id + "'(" + stream.master.id + "). Disconnecting...");
		limeTalks.disconnect();
		ExternalInterface.call("closeStream", stream.id, stream.name);
	}else{
		log("User '" + user.name + "' has left the stream '" + stream.id + "'");
	}
}

private function onStreamUpdate(event:LimeEvent) : void 
{
	log("Stream '" + event.params.stream.id + "' has been updated");
}

public function onConnectionNetStatus(event:NetStatusEvent) : void {
	log(event.info.code);
	// did we successfully connect
	if(event.info.code == "NetConnection.Connect.Success") {
		//Alert.show("Successful Connection", "Information");
		//connectionStatusLabel.text = "Connected";
		//		setupOutgoingDevices();
	}/* else if(event.info.code == "NetConnection.Connect.Closed"){
	connectionStatusLabel.text = "Disconnected";
	} else {
	connectionStatusLabel.text = "Failed to connect";
	//Alert.show("Unsuccessful Connection", "Information");
	}*/
}

private function setupOutgoingDevices() : void {
	//setup outgoing devices
	camera = Camera.getCamera();
	
	/*
	
	cam.addEventListener(flash.events.StatusEvent.STATUS, onCameraStatus);
	onCameraStatus (null);
	}
	private function onCameraStatus (e: flash.events.StatusEvent):void{
	if (! cam.muted){
	videoPublisher.visible = true;
	videoPublisher.attachCamera(cam); }
	else
	videoPublisher.visible = false;
	}
	
	*/
	var videoWidth:int = Application.application.parameters.vw;
	var videoHeight:int = Application.application.parameters.vh;
	var videoFps:int = Application.application.parameters.vf;
	var videoQuality:int = Application.application.parameters.vq;

	Alert.show( "информация о камере: name: "+camera.name+", resolution: "+ camera.width+
			" * "+ camera.height+", fps: "+ camera.fps);

	camera.setQuality(0, videoQuality);
	camera.setMode(videoWidth, videoHeight, videoFps);
	//Alert.show("camera.quality: " + camera.quality);
	//outSipmeVideo.setWidth(camera.width);
	//outSipmeVideo.setHeight(camera.height);
	microphone = Microphone.getMicrophone();	
}

private function setupIncominStream() : void {	
	log("setup incoming stream '" + streamId + "'");
	inStream = new NetStream(limeTalks.connection);
	inStream.play("stream" + streamId);
	//setup incoming video and attach incoming stream
	//	inVideo = new Video();
	//	inVideo.attachNetStream(inStream);
	
	outSipmeVideo.attachNetStream(inStream);
}

private function stopIncominStream() : void {
	inStream.close();
	outSipmeVideo.reset();
}

private function setupOutgoingStream() : void {
	log("setup outgoing stream '" + streamId + "'");
	//setup outgoing stream
	outStream = new NetStream(limeTalks.connection);
	//if(outputCameraCheckBox.selected){
	outStream.attachCamera(camera);
	outSipmeVideo.attachCamera(camera);
	//}
	//if(outputMicrophoneCheckBox.selected){
	outStream.attachAudio(microphone);	
	//}	
	
	outStream.publish("stream" + streamId);
	
	//setup outgoing video and attach outgoing devices
	//	outVideo = new Video();
	//	outVideo.attachCamera(camera);	
}

private function stopOutgoingStream() : void {
	outStream.close();
	outSipmeVideo.reset();	
}

//protected function publishStreamCheckBox_clickHandler(event:MouseEvent):void
//{
//	if(publishStreamCheckBox.selected){
//		setupOutgoingStream();
//	}else{
//		stopOutgoingStream();
//	}
//}
//
//protected function receiveStreamCheckBox_clickHandler(event:MouseEvent):void
//{
//	if(receiveStreamCheckBox.selected){
//		setupIncominStream();
//	}else{
//		stopIncominStream();
//	}
//}

private function log(msg:String):void {
	//logTextArea.text += msg + "\n";
	trace(msg + "\n");
	//Alert.show(msg, "Information");
}

private function onMessageReceive(event:LimeEvent):void {
	var message:String = event.params.message;
	var userName:String = event.params.user;
	ExternalInterface.call("chatPublishMessage", userName, message);
}

private function chatSendMessage(message:String):void {
	limeTalks.chatSendMessage(message);
}